import {
	getIMToken,
	changeIMUserStatus
} from '@/api/api.js'
import envParams from '@/api/env.js'

import commonData from './commonData'

import {
	toast
} from './utils'

// #ifdef APP-PLUS
import appUpdate from '@/utils/appUpdate.js'
import RCIMIWEngine from "@/uni_modules/RongCloud-IMWrapper-V2/js_sdk/RCIMEngine"
// #endif

// #ifndef APP-PLUS
import * as RongIMLib from '@rongcloud/imlib-next'
// #endif

let imSupport = {
	appKey: envParams.VUE_APP_RONGYUN_KEY,
	engine: null,
	lastMessageUId: '',
	noticeIM: function(type) {
		let src = '/static/audio/' + type + '.mp3'
		const innerAudioContext = uni.createInnerAudioContext();
		innerAudioContext.autoplay = true;
		innerAudioContext.src = src //铃声文件的路径
		innerAudioContext.onPlay(() => {
			console.log('开始播放 ' + src);
		});
		innerAudioContext.onError((res) => {
			console.log('noticeIM error', res);
		});
	},
	initIMEngine: async function() {
		if (this.appKey) {
			// #ifdef APP-PLUS
			console.log('init APP IM', this.appKey)
			// 初始化配置，没有可传 {}
			// kickReconnectDevice 设置断线重连时是否踢出当前正在重连的设备
			let options = {
				kickReconnectDevice: false
			}
			this.engine = await RCIMIWEngine.create(this.appKey, options);
			this.engine.setOnConnectionStatusChangedListener((res) => {
				//SDK 与融云服务器的连接状态 https://docs.rongcloud.cn/uni-app-imlib/connectmgr/listener
				console.log('res', res)
			});
			console.log('初始化引擎with key ' + this.appKey, this.engine);
			// #endif

			// #ifndef APP-PLUS
			console.log('init H5 IM', this.appKey)
			if (RongIMLib) {
				await RongIMLib.init({
					appkey: this.appKey
				});
			} else {
				uni.showToast({
					title: '当前IM不可用！',
					icon: 'error',
					duration: 3000
				})
			}
			// #endif
		}
	},
	initConnect: function(token) {
		// #ifdef APP-PLUS
		this.initConnectApp(token)
		// #endif
		// #ifndef APP-PLUS
		this.initConnectH5(token)
		// #endif
	},
	initConnectApp: async function(token) {
		let callback = {
			onDatabaseOpened: (res) => {
				//...
			},
			onConnected: (res) => {
				//...
			}
		};
		let code = await engine.connect(token, 6000, callback);
		console.log('connect code', code)
	},
	initConnectH5: function(token) {
		let that = this
		console.log('initConnectH5 with token', token)
		try {
			const Events = RongIMLib.Events
			// 移除具体事件的所有监听器
			RongIMLib.removeEventListeners(Events.CONNECTING)
			RongIMLib.removeEventListeners(Events.CONNECTED)
			RongIMLib.removeEventListeners(Events.DISCONNECT)
			RongIMLib.removeEventListeners(Events.SUSPEND)
			RongIMLib.removeEventListeners(Events.MESSAGES)
			/**
			 * 正在链接的事件状态
			 */
			RongIMLib.addEventListener(Events.CONNECTING, () => {
				console.log('正在链接...')
			})

			/**
			 * 链接到服务器会触发这个事件
			 */
			RongIMLib.addEventListener(Events.CONNECTED, () => {
				console.log('连接成功')
			})

			/**
			 * 手动调用 disconnect 方法或者用户被踢下线 会触发这个事件
			 */
			RongIMLib.addEventListener(Events.DISCONNECT, (code) => {
				console.log('连接中断，需要业务层进行重连处理 ->', code)
				// this.$notify({ type: 'danger', message: "当前咨询已断开链接，请手动刷新重试！" })
				// this.$Message.error('当前咨询已断开链接，请尝试重新接入！')
				uni.showToast({
					title: '即时通信IM已断开链接！',
					icon: 'error',
					duration: 3000
				})
				this.noticeIM('offline')
				// toast("即时通信IM已断开链接！")
				uni.$emit('changeIMStatus', 'offline')
			})

			/**
			 * 链接出问题时，内部进行重新链接，会触发这个事件
			 */
			RongIMLib.addEventListener(Events.SUSPEND, (code) => {
				console.log('链接中断，SDK 会尝试重连，业务层无需关心')
				// 5.1.2 版本开始，事件回调中会引起中断的 code 状态码
				toast("即时通信IM链接中断，正在尝试重连！")
				console.log(`code -> ${code}`)
			})

			/**
			 * reconnectKickEnable 参数详细说明：
			 * 设置 reconnectKickEnable 为 true： 如果重连时发现已有别的桌面端设备在线，将不再重连，不影响已正常登录的桌面端设备。
			 * 设置 reconnectKickEnable 为 false：如果重连时发现已有别的桌面端设备在线，将踢出已在线的桌面端设备，使当前设备上线。
			 */
			RongIMLib.connect(token, false).then(async (resRY) => {
				console.log('connect data', resRY)
				if (resRY.code === RongIMLib.ErrorCode.SUCCESS) {
					console.log("即时通信IM链接成功 ", resRY.data.userId)
					this.noticeIM('online')
					uni.$emit('changeIMStatus', 'online')
				} else {
					toast(resRY?.message || 'IM链接失败！')
					uni.$emit('changeIMStatus', 'offline')
					uni.showToast({
						title: resRY?.message || 'IM链接失败！',
						icon: 'error',
						duration: 3000
					})
				}
			})

			RongIMLib.addEventListener(Events.MESSAGES, async (ev) => {
				console.log('收到的消息...', ev.messages)
				ev.messages.forEach(item => {
					if (item.messageUId != this.lastMessageUId) {
						this.lastMessageUId = item.messageUId
						uni.$emit('receiveMsg', item)
					} else {
						console.log('repeat message...')
					}
				})
			})
		} catch (error) {
			console.log('initIM error', error)
		}
	},
	// 定义消息投送目标会话, 这里定义一个群组类型会话
	sendDirectMessage: async function(msg, messageType, targetId, toUserIds) {
		// #ifdef APP-PLUS
		await this.sendDirectMessageApp(msg, messageType, targetId, toUserIds)
		// #endif
		// #ifndef APP-PLUS
		await this.sendDirectMessageH5(msg, messageType, targetId, toUserIds)
		// #endif
	},
	sendDirectMessageH5: function(msg, messageType, targetId, toUserIds) {
		let messageObj;
		switch (messageType) {
			case 'TxtMsg':
				messageObj = new RongIMLib.TextMessage({
					...msg
				})
		}
		const conversationType = {
			conversationType: RongIMLib.ConversationType.GROUP,
			targetId: targetId
		}
		if (toUserIds && toUserIds.length > 0) {
			RongIMLib.sendMessage(conversationType, messageObj, {
				directionalUserIdList: toUserIds,
				// 消息发送前的回调，可以使用此回调返回的 message 用于列表渲染
				onSendBefore: (message) => {
					console.log('消息发送前的回调', message)
				},
			}).then(res => {
				if (res.code === RongIMLib.ErrorCode.SUCCESS) {
					// 消息发送成功，可以根据返回结果中的 messageId 字段将列表中的该消息状态改为发送成功。
					console.log('消息发送成功', res.data)
				} else {
					console.log('消息发送失败', res.code, res.msg)
				}
			})
		} else {
			RongIMLib.sendMessage(conversationType, messageObj, {
				// 消息发送前的回调，可以使用此回调返回的 message 用于列表渲染
				onSendBefore: (message) => {
					console.log('消息发送前的回调', message)
				},
			}).then(res => {
				if (res.code === RongIMLib.ErrorCode.SUCCESS) {
					// 消息发送成功，可以根据返回结果中的 messageId 字段将列表中的该消息状态改为发送成功。
					console.log('消息发送成功', res.data)
				} else {
					console.log('消息发送失败', res.code, res.msg)
				}
			})
		}
	},
	sendDirectMessageApp: async function(msg, messageType, targetId, toUserIds) {
		let messageObj;
		switch (messageType) {
			case 'TxtMsg':
				messageObj = await this.engine.createTextMe(
					RCIMIWMessageType.text,
					targetId,
					null,
					msg.content,
				);

				break
		}
		if (messageObj) {
			messageObj.extra = msg.extra
			let listener = {
				onMediaMessageSaved: (res) => {
					//...
				},
				onMediaMessageSending: (res) => {
					//...
				},
				onSendingMediaMessageCanceled: (res) => {
					//...
				},
				onMediaMessageSent: (res) => {
					//...
				}
			};
			let code = await this.engine.sendMediaMessage(messageObj, listener);

		}
	},
	destory: function() {
		try {
			if (RongIMLib) {
				console.log('RongIMLib', RongIMLib)

				RongIMLib.disconnect().then(() => {
					console.log('成功断开')
				})
			} else if (this.engine) {
				this.engine.destroy()
				this.engine = null
			}
		} catch (err) {
			console.log('destory error', destory)
		}
	}
}

export default imSupport